angular.module('wf-log', [])

.constant 'logDelegate', ($delegate) ->
    _$log = (($log) ->
        log   : $log.log
        info  : $log.info
        warn  : $log.warn
        debug : $log.debug
        error : $log.error
    )($delegate)

    dataPool = []
    defaultData = {}
    backend = undefined
    debug   = undefined
    # Partial application to pre-capture a logger function
    prepareLogFn = (logFn, type, className = '') ->
        # Invoke the specified `logFn` with the supplant functionality...
        enhancedLogFn = ->
            args = Array.prototype.slice.call(arguments)

            # TODO 实现更好的line number
            # http://stackoverflow.com/questions/16300393/need-reference-to-the-log-log-call-line-number

            #stack = (new Error()).stack.split('\n').slice(1)
            #stack.shift()
            #stack = stack[0]

            logData = _.extend
                'time'     : (new Date()).getTime()
                'type'     : type
                'module'   : className
                'position' : 'null'
                'data'     : args[0].toString()
            , defaultData
            dataPool.push logData
            if debug and (dataPool.length > 20 or type == 'error') # 如果超过20个或者遇到了错误，则立即提交日志
                xmlhttp = new XMLHttpRequest()
                xmlhttp.open('POST', backend)
                xmlhttp.setRequestHeader('Content-Type', 'application/json;charset=UTF-8')
                xmlhttp.send(JSON.stringify(dataPool))
                dataPool = []

            logFn.apply(null,  args)

        # Special... only needed to support angular-mocks expectations
        enhancedLogFn.logs = []

        enhancedLogFn

    funArr = ['log', 'info', 'warn', 'debug', 'error']
    getInstance = (className) ->
        obj = {}
        _.each funArr, (funName) ->
            obj[funName] = prepareLogFn _$log[funName], funName, className
        obj

    _.each funArr, (funName) ->
        $delegate[funName] = prepareLogFn $delegate[funName], funName

    # Add special method to AngularJS $log
    $delegate.getInstance = getInstance
    $delegate.init = (_project, _guid, _backend, _debug = false) ->
        defaultData = {project: _project, guid: _guid}
        backend = _backend
        debug = _debug
    $delegate
